package com.adcc.monitoragent.core.service;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import org.quartz.DisallowConcurrentExecution;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.quartz.PersistJobDataAfterExecution;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.adcc.monitoragent.bean.MongoBean;
import com.adcc.monitoragent.log.ServiceLogger;
import com.adcc.monitoragent.send.MessageSend;
import com.adcc.monitoragent.util.Constants;
import com.adcc.monitoragent.util.ProtertiesUtil;
import com.mongodb.DB;
import com.mongodb.Mongo;

/**
 * ip + port 唯一确定 集群监控
 * 
 * @author yycoder
 * 
 */
@PersistJobDataAfterExecution   
@DisallowConcurrentExecution
public class MongoService implements Job {
	private final static Logger log = LoggerFactory.getLogger(MongoService.class);
	private static Map<String, Mongo> mongos = new ConcurrentHashMap<String, Mongo>();
	public static final String dbName = "admin";
	private static Map<String, MongoBean> lastMongoBeanMap = new ConcurrentHashMap<String, MongoBean>();

	public static MongoBean getInfo(String ip, int port, String username,
			String password) {
		MongoBean mongoBean = new MongoBean();
		mongoBean.setIp(ip);
		mongoBean.setPort(String.valueOf(port));
		Mongo mongo = mongos.get(ip + ":" + port);
		try {
			DB db = null;
			if (mongo == null) {
				try {
					mongo = new Mongo(ip, port);
					db = mongo.getDB(dbName);
					if (!db.isAuthenticated())
						db.authenticate(username, password.toCharArray());
					mongos.put(ip + ":" + port, mongo);
				} catch (Exception e) {
					log.error("mongo连接创建异常" + e.getMessage());
					mongo.close();
					mongoBean.setStatus(Constants.STATUS_ERROR);
					return mongoBean;
				}
			} else {
				db = mongo.getDB(dbName);
			}
			db.command("select 1");
			mongoBean.setStatus(Constants.STATUS_OK);
		} catch (Exception e) {
			mongoBean.setStatus(Constants.STATUS_ERROR);
			log.error("mongo连接中断异常" + e.getMessage());
		}
		
		return mongoBean;
	}
	
	@Override
	public void execute(JobExecutionContext arg0) throws JobExecutionException {
		log.debug("定时执行任务。。。。。。。。。。。。");
		for (Object objStr : ProtertiesUtil.getMongodbConnectString()) {
			try {
				String[] s = objStr.toString().split(":");
				MongoBean mongo = MongoService.getInfo(s[0], Integer.parseInt(s[1]),
						ProtertiesUtil.getMongodbUsername(), ProtertiesUtil.getMongodbPassword());
				String key = mongo.buildKey();
				MongoBean lastMongoBean = lastMongoBeanMap.get(key);
				boolean statusChange = lastMongoBean != null && !lastMongoBean.getStatus().equals(mongo.getStatus());
				if(mongo.getStatus().equals(Constants.STATUS_ERROR) && statusChange) {//如果状态异常 并且 状态改变
					log.warn("Mongo状态正常转异常，休眠2秒重试，防止误判");
					try {
						Thread.sleep(2000);
					} catch (InterruptedException e) {
					}
					mongo = MongoService.getInfo(s[0], Integer.parseInt(s[1]),
							ProtertiesUtil.getMongodbUsername(), ProtertiesUtil.getMongodbPassword());
					if(mongo.getStatus().equals(Constants.STATUS_ERROR)) {//状态还是异常
						String desc = "服务停止";
						ServiceLogger.error(mongo.getIp(), mongo.getPort(), "mongo", desc);
					}
				} else if(statusChange){//状态由异常转正常
					String desc = "服务启动";
					ServiceLogger.info(mongo.getIp(), mongo.getPort(), "mongo", desc);
				}
				
				lastMongoBeanMap.put(key, mongo);
				//转发消息
				MessageSend.sendMsg(mongo);
			} catch (Exception e) {
				log.error("Mongo定时任务执行失败:" + objStr +  e.getMessage());
			}
		}
		log.debug("完成任务。。。。。。。。。。。。");
	}

	public static void main(String[] args) throws Exception {
		MongoBean mongo = MongoService.getInfo("192.168.243.78", 28011,
				"admin", "admin");
		System.out.println(mongo);
	}
}
